Skip to content

04 学以致用 - 日常工作中的 bash 脚本 -1

主机资源利用率监控

bash
#!/bin/bash

while true; do
    # 获取当前CPU利用率
    cpu_usage=$(top -b -n 2 -d 1 | grep "Cpu(s)" | tail -n 1 | awk '{print $2}')

    # 获取当前内存利用率
    mem_usage=$(free | grep Mem | awk '{printf "%.2f", $3/$2 * 100.0}')

    # 获取当前磁盘利用率
    disk_usage=$(df -h | awk '$NF=="/" {printf "%s", $5}')

    # 将结果写入日志文件
    echo "$(date +"%Y-%m-%d %H:%M:%S") CPU: $cpu_usage% MEM: $mem_usage% DISK: $disk_usage" >>/var/log/sysstat.log

    # 等待 2 秒
    sleep 2
done

获取 CPU 利用率

bash
  0904 git:(main) top -b -n 2 -d 1 | grep "Cpu(s)"
%Cpu(s):  1.6 us,  0.0 sy,  0.0 ni, 98.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu(s):  0.2 us,  0.5 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

  0904 git:(main) top -b -n 2 -d 1 | grep "Cpu(s)" | tail -n 1
%Cpu(s):  0.5 us,  0.7 sy,  0.0 ni, 98.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

  0904 git:(main) top -b -n 2 -d 1 | grep "Cpu(s)" | tail -n 1 | awk '{print $2}'
0.2
  • top -b -n 2 -d 1
    • top 显示系统资源使用情况。
    • -b 以“批处理模式”运行,适合脚本中使用,因为它不需要交互式界面。
    • -n 2 运行两次,因为第一次的输出可能会包含初始化数据,而我们通常只关心第二次的结果。
    • -d 1 每次运行之间的时间间隔为 1 秒。默认情况下,top 会每 3 秒更新一次。
  • grep "Cpu(s)":在 top 的输出中查找包含 "Cpu(s)" 的行,它通常显示 CPU 的使用信息。
  • tail -n 1:只取输出的最后一行。由于 top 运行了两次,第一行可能是第一次运行的结果,第二行才是我们真正关心的最新结果。
  • awk '{print $2}'awk 是一个文本处理工具,它会从 CPU 的输出行中提取第二列数据,这通常是用户态 CPU 使用率(us 字段,表示 CPU 使用了多少百分比用于用户进程)。

获取内存利用率

bash
  0904 git:(main) free # 查看内存使用情况
               total        used        free      shared  buff/cache   available
Mem:         3746560     2665348      649816       10268      695220     1081212
Swap:              0           0           0

  0904 git:(main) free | grep Mem # 过滤出 Mem 行
Mem:         3746560     2664052      651108       10268      695224     1082508

  0904 git:(main) free | grep Mem | awk '{print $1, $2, $3}' # 以空格为分隔符,打印第一列、第二列、第三列
Mem: 3746560 2673360

  0904 git:(main) free | grep Mem | awk '{print $3/$2}' # 计算内存使用率
0.712568

  0904 git:(main) free | grep Mem | awk '{print $3/$2*100}' # 计算内存使用率,结果为百分比
71.0634

  0904 git:(main) free | grep Mem | awk '{printf "%.2f",  $3/$2*100}'
71.21#
  0904 git:(main) free | grep Mem | awk '{printf "%.2f\n",  $3/$2*100}' # 计算内存使用率,结果为百分比,并保留两位小数
71.03
  • free:显示系统内存使用情况。
  • grep Mem:从 free 的输出中选择包含内存总量和使用情况的那一行。
  • awk '{printf "%.2f", $3/$2 * 100.0}':使用 awk 处理这行数据,其中:
    • $3 是已用内存量。
    • $2 是总内存量。
    • $3/$2 * 100.0 计算内存使用率,结果乘以 100 表示百分比。
    • printf "%.2f" 将结果格式化为保留两位小数。

获取磁盘利用率

bash
  0904 git:(main) df -h # 查看磁盘使用情况
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs            4096       0      4096   0% /dev
tmpfs            1873280      24   1873256   1% /dev/shm
tmpfs             749312    8696    740616   2% /run
/dev/vda1       82446148 4618216  74351412   6% /
tmpfs             374656       0    374656   0% /run/user/0

  0904 git:(main) df -h # 以人类可读的格式显示
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        4.0M     0  4.0M   0% /dev
tmpfs           1.8G   24K  1.8G   1% /dev/shm
tmpfs           732M  8.5M  724M   2% /run
/dev/vda1        79G  4.5G   71G   6% /
tmpfs           366M     0  366M   0% /run/user/0

  0904 git:(main) df -h | grep -e "/$" # 过滤出根目录
/dev/vda1        79G  4.5G   71G   6% /

  0904 git:(main) df -h | grep -e "/$" | awk '{ print $(NF-1)}' # 以空格为分隔符,打印倒数第二列(磁盘使用率)
6%

  0904 git:(main) df -h | awk '$NF=="/"' # 过滤出根目录
/dev/vda1        79G  4.5G   71G   6% /

  0904 git:(main) df -h | awk '$NF=="/" {print $5}' # 以空格为分隔符,打印第五列(磁盘使用率)
6%
  • df -h:显示磁盘空间使用情况。-h 表示以人类可读的格式显示(即带单位,如 GB、MB 等)。
  • awk '$NF=="/" {printf "%s", $5}'
    • $NF=="/":选择挂载点是根目录 / 的行($NF 表示最后一列,通常是挂载点)。
    • {printf "%s", $5}:从选中的行中提取第五列数据(即磁盘使用率百分比)。

写入日志文件

bash
echo "$(date +"%Y-%m-%d %H:%M:%S") CPU: $cpu_usage% MEM: $mem_usage% DISK: $disk_usage" >>/var/log/sysstat.log
  • $(date +"%Y-%m-%d %H:%M:%S"):使用 date 命令获取当前日期和时间,格式为 YYYY-MM-DD HH:MM:SS
  • echo ... >>/var/log/sysstat.log:将监控的 CPU、内存、磁盘利用率和当前时间一起格式化输出,并追加到日志文件 /var/log/sysstat.log 中。>> 表示追加写入,不覆盖原有内容。

实验代码

bash
  0904 git:(main) bash monitor_host_resources.sh & # 后台运行脚本 监控主机资源
[1] 1814558

  0904 git:(main) stress-ng -c 1 & # 后台运行 stress-ng 命令,模拟 CPU 负载
[2] 1815059

  0904 git:(main) stress-ng: info:  [1815059] defaulting to a 1 day, 0 secs run per stressor
stress-ng: info:  [1815059] dispatching hogs: 1 cpu

  0904 git:(main) jobs # 查看后台运行的任务
[1]  - running    bash monitor_host_resources.sh
[2]  + running    stress-ng -c 1

  0904 git:(main) kill %2 # 终止后台运行的 stress-ng 命令
stress-ng: info:  [1815059] skipped: 0
stress-ng: info:  [1815059] passed: 0
stress-ng: info:  [1815059] failed: 1: cpu (1)
stress-ng: info:  [1815059] metrics untrustworthy: 0
  0904 git:(main) stress-ng: info:  [1815059] unsuccessful run completed in 32.53 secs

[2]  + 1815059 exit 2     stress-ng -c 1

  0904 git:(main) cat /var/log/sysstat.log # 查看日志文件
2024-10-04 10:33:33 CPU: 0.3% MEM: 71.14% DISK: 6%
2024-10-04 10:33:41 CPU: 0.2% MEM: 70.97% DISK: 6%
2024-10-04 10:33:50 CPU: 0.5% MEM: 71.02% DISK: 6%
2024-10-04 10:33:58 CPU: 24.4% MEM: 71.12% DISK: 6%
2024-10-04 10:34:06 CPU: 24.4% MEM: 70.94% DISK: 6%
2024-10-04 10:34:14 CPU: 24.3% MEM: 71.11% DISK: 6%